package linter.linterjava.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import linter.linterjava.POJO.DO.KnowledgeBase;
import linter.linterjava.POJO.DO.Note;
import linter.linterjava.POJO.DO.NoteKnowledgebase;
import linter.linterjava.POJO.DTO.NoteKnowledgebaseDTO;
import linter.linterjava.POJO.UtilDTO.MoveUtilDTO;
import linter.linterjava.POJO.UtilDTO.PageInfoDTO;
import linter.linterjava.custom.ConstantPublicWay;
import linter.linterjava.mapper.KnowledgeBaseMapper;
import linter.linterjava.mapper.NoteMapper;
import linter.linterjava.service.NoteKnowledgebaseService;
import linter.linterjava.mapper.NoteKnowledgebaseMapper;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static linter.linterjava.custom.ConstantPublicWay.getList;
import static linter.linterjava.custom.ConstantPublicWay.getPageInfo;
import static linter.linterjava.custom.CustomResultType.*;

/**
 * @author 北煜
 */
@Service
public class NoteKnowledgebaseServiceImpl extends ServiceImpl<NoteKnowledgebaseMapper, NoteKnowledgebase>
        implements NoteKnowledgebaseService {

    @Resource
    NoteKnowledgebaseMapper noteKnowledgebaseMapper;
    @Resource
    NoteMapper noteMapper;
    @Resource
    KnowledgeBaseMapper knowledgeBaseMapper;

    @Override
    @CacheEvict(value = "noteKnowledgebase", key = "#uuid + ':*'")
    public String group(KnowledgeBase knowledgeBase, Long uuid){
        if (knowledgeBase.getKnowledgebaseId() == null && knowledgeBase.getNoteId() == null){
            return DATA_NOT_EXIST;
        }
        if (noteKnowledgebaseMapper.selectById(knowledgeBase.getKnowledgebaseId()).getId() == null &&
                noteMapper.selectById(knowledgeBase.getNoteId()).getId() == null){
            return DATA_NOT_EXIST;
        }
        KnowledgeBase knowledgeBaseDTO = new KnowledgeBase();
        knowledgeBaseDTO.setKnowledgebaseId(knowledgeBase.getKnowledgebaseId());
        knowledgeBaseDTO.setNoteId(knowledgeBase.getNoteId());
        int flag = knowledgeBaseMapper.insert(knowledgeBaseDTO);
        Note note = new Note();
        Date date = new Date();
        note.setNoteKnowledgebaseId(knowledgeBase.getKnowledgebaseId());
        note.setUpdataTime(date);
        flag += noteMapper.update(note,new QueryWrapper<Note>()
                .eq("id", knowledgeBase.getNoteId()).eq("user_id",uuid));
        return flag > 0 ? ADD_SUCCESS : ADD_ERROR;
    }

    @Override
    @CacheEvict(value = "noteKnowledgebase", key = "#uuid + ':*'")
    public String delNoteGruop(Long noteKnowledgeBaseId, Long uuid) {
        Date date = new Date();
        Note note = new Note();
        KnowledgeBase knowledgeBase = new KnowledgeBase();
        NoteKnowledgebase noteKnowledgebase = new NoteKnowledgebase();
        noteKnowledgebase.setUpdataTime(date);
        noteKnowledgebase.setIsDelete(1);
        int flag = noteKnowledgebaseMapper.update(noteKnowledgebase, new QueryWrapper<NoteKnowledgebase>()
                .eq("id", noteKnowledgeBaseId).eq("user_id",uuid));
        flag += knowledgeBaseMapper.deleteById(noteKnowledgeBaseId);
        note.setUpdataTime(date);
        note.setNoteKnowledgebaseId(0L);
        flag += noteMapper.update(note, new QueryWrapper<Note>()
                .eq("note_knowledgebase_id", noteKnowledgeBaseId).eq("user_id",uuid));
        return flag >= 3 ? DELETE_SUCCESS : DELETE_ERROR;
    }

    @Override
    @CacheEvict(value = "noteKnowledgebase", key = "#uuid + ':*'")
    public String moveNote(MoveUtilDTO moveUtilDTO, Long uuid) {
        // 获得老分组中的所有笔记id
        List<Long> noteIds = getList(new QueryWrapper<KnowledgeBase>()
                .eq("knowledgeBase_id", moveUtilDTO.getOldId()),knowledgeBaseMapper)
                .stream().map(KnowledgeBase::getNoteId).collect(Collectors.toList());
        // 将老分组中的笔记id清楚
        int flag = knowledgeBaseMapper.deleteById(moveUtilDTO.getOldId());
        // 将笔记移动到新分组中
        for (Long noteId : noteIds) {
            KnowledgeBase knowledgeBase = new KnowledgeBase();
            knowledgeBase.setKnowledgebaseId(moveUtilDTO.getNewId());
            knowledgeBase.setNoteId(noteId);
            flag += knowledgeBaseMapper.insert(knowledgeBase);
        }
        // 将新分组中与老分组重合的剔除
        List<Long> newNoteIds = getList(new QueryWrapper<KnowledgeBase>()
                .eq("knowledgeBase_id", moveUtilDTO.getNewId()),knowledgeBaseMapper)
                .stream().map(KnowledgeBase::getNoteId).collect(Collectors.toList());
        for (Long noteId : newNoteIds) {
            if (noteIds.contains(noteId)) {
                knowledgeBaseMapper.delete(new QueryWrapper<KnowledgeBase>()
                        .eq("note_id", noteId).eq("knowledgebase_id", moveUtilDTO.getNewId()));
            }
        }
        return flag < 1 ? UPDATE_ERROR : UPDATE_SUCCESS;
    }

    @Override
    @CacheEvict(value = "noteKnowledgebase", key = "#uuid + ':*'")
    public String delNoteGruopItem(Long noteKnowledgeBaseId, Long noteId, Long uuid) {
        int flag = knowledgeBaseMapper.delete(new QueryWrapper<KnowledgeBase>()
                .eq("knowledgeBase_id", noteKnowledgeBaseId).eq("note_id", noteId));
        return flag < 0 ? DELETE_ERROR : DELETE_SUCCESS;
    }

    @Override
    @CacheEvict(value = "noteKnowledgebase", key = "#uuid + ':*'")
    public String createGroup(NoteKnowledgebaseDTO noteKnowledgebaseDTO, Long uuid) {
        Date date = new Date();
        NoteKnowledgebase noteKnowledgebase = new NoteKnowledgebase();
        noteKnowledgebase.setKnowledgebaseName(noteKnowledgebaseDTO.getKnowledgebaseName());
        noteKnowledgebase.setUserId(uuid);
        noteKnowledgebase.setKnowledgebaseType(noteKnowledgebaseDTO.getKnowledgebaseType());
        noteKnowledgebase.setKnowledgebaseIntro(noteKnowledgebaseDTO.getKnowledgebaseIntro());
        noteKnowledgebase.setCreateTime(date);
        noteKnowledgebase.setUpdataTime(date);
        System.out.println(noteKnowledgebase);
        int flag = noteKnowledgebaseMapper.insert(noteKnowledgebase);
        return flag != 1 ? CREATION_ERROR : CREATION_SUCCESS;
    }

    @Override
    @Cacheable(value = "noteKnowledgebase", key = "#uuid + ':selectGroup:' + #pageInfoDTO.pageNum + ':' + #pageInfoDTO.pageSize")
    public PageInfo<NoteKnowledgebase> selectGroup(PageInfoDTO pageInfoDTO, Long uuid) {
        return getPageInfo(pageInfoDTO, new QueryWrapper<NoteKnowledgebase>()
                .eq("user_id", uuid).eq("is_delete",0), noteKnowledgebaseMapper);
    }

    @Override
    @Cacheable(value = "noteKnowledgebase", key = "#uuid + ':selectGroupById:' + #knowledgeBaseDTO.getId() + ':' + #pageNum + ':' + #pageSize")
    public PageInfo<Note> selectGroupById(NoteKnowledgebaseDTO knowledgeBaseDTO, Long uuid) {
        int pageSize = Optional.ofNullable(knowledgeBaseDTO.getPageSize()).orElse(10);
        int pageNum = Optional.ofNullable(knowledgeBaseDTO.getPageNum()).orElse(1);
        PageHelper.startPage(pageNum, pageSize);

        List<Long> noteIds = getList(new QueryWrapper<KnowledgeBase>()
                .eq("knowledgeBase_id", knowledgeBaseDTO.getId()),knowledgeBaseMapper)
                .stream().map(KnowledgeBase::getNoteId).collect(Collectors.toList());
        if (noteIds.isEmpty()) {
            List<Note> list = new ArrayList<>();
            return new PageInfo<>(list);
        }
        List<Note> notes = noteMapper.selectBatchIds(noteIds);
        return new PageInfo<>(notes);
    }

    @Override
    @CacheEvict(value = "noteKnowledgebase", key = "#uuid + ':*'")
    public String updateGroupName(NoteKnowledgebaseDTO knowledgeBaseDTO, Long uuid) {
        Date date = new Date();
        NoteKnowledgebase noteKnowledgebase = new NoteKnowledgebase();
        noteKnowledgebase.setKnowledgebaseName(knowledgeBaseDTO.getKnowledgebaseName());
        noteKnowledgebase.setUpdataTime(date);
        int flag = noteKnowledgebaseMapper.update(noteKnowledgebase,
                new QueryWrapper<NoteKnowledgebase>()
                        .eq("id", knowledgeBaseDTO.getId()).eq("user_id", uuid).eq("is_delete", 0));
        return flag > 0 ? UPDATE_SUCCESS : UPDATE_ERROR;
    }

}
